runtime/wasm: add opt-in non-moving collector (based on #2197) - #2203
Draft
cpunion wants to merge 30 commits into
Draft
runtime/wasm: add opt-in non-moving collector (based on #2197)#2203cpunion wants to merge 30 commits into
cpunion wants to merge 30 commits into
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…/wasm-wasi-single-worker
…orker-asyncify-scheduler # Conflicts: # internal/build/source_patch_test.go
…/wasm-wasi-single-worker
# Conflicts: # .github/workflows/llgo.yml
…orker-asyncify-scheduler # Conflicts: # runtime/internal/runtime/z_default.go
…/wasm-wasi-single-worker
This was referenced Jul 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends on #2197.
Part of #2152 (stage T).
Problem
Wasm currently selects
nogcbecause BDWGC is unavailable. That leaves J32, J64, and P1 without a runtime-owned allocator, reclamation, memory statistics, or linear-memory growth policy.Enabling collection by default is not yet correct: LLGo may keep a live Go pointer only in an SSA/wasm local across
runtime.GC, and a linear-stack scan cannot observe that value. Suspended-G root publication is also intentionally deferred to stage D. This PR therefore provides the collector behind the temporary internalllgo_wasm_gcbuild tag while preserving the existing defaultnogcbehavior.Implementation
runtime.ReadMemStatsshims.__global_base,__data_end,__heap_base, the active linear stack boundary, and WebAssembly page growth.emscripten_builtin_*allocation entry points to the collector.-sMALLOC=noneis injected only whenllgo_wasm_gcis selected, so default wasm builds retain their current allocator.llgo_wasm_gcwith threaded P1 builds; the collector is intentionally single-worker and requiresLLGO_WASI_THREADS=0for P1.The collector is single-worker. It scans linear-memory globals and the active linear stack, but does not claim that wasm locals or suspended Asyncify contexts are roots. Stage D will add compiler-maintained root records and then remove the opt-in gate.
Validation
The fixture covers:
runtime.ReadMemStatsallocation and reclamation counters;llgo build -target wasm -tags=llgo_wasm_gcwasm gc okGOOS=js GOARCH=wasm ... -tags=llgo_wasm_gcwasm gc okGOOS=wasip1 GOARCH=wasm LLGO_WASI_THREADS=0wasm-tools, and executed with Wasmtime 39 and exceptions enabled:wasm gc okLocal bounded checks used
GOMAXPROCS=2and-p=1. The full macOSinternal/buildandinternal/crosscompiletests passed with 73.9% and 80.9% package coverage; both newly added build helpers report 100% coverage. The runtime module passed on macOS and in an Ubuntu 24.04 container limited to 15 GiB and 2 CPUs.The updated #2197-based stack passes the full GitHub Ubuntu/macOS matrix and Codecov; local macOS target and coverage checks also pass.
Native and embedded cost
Compared with the direct #2197 base using identical inputs:
cortex-m-qemuembedded ELFs are byte-for-byte identical (same SHA-256), with.text92 bytes and total sections 4,353 bytes.Wasm-only sources and the allocator linker option are excluded unless the internal tag is selected, so this PR adds no default native, embedded, or wasm runtime path.
Opt-in wasm size
Using the same minimal
wasm-runtimefixture for both modes:nogcThese bytes are paid only by explicitly tagged builds. Runtime throughput and pause measurements remain follow-up data once compiler-maintained roots make collection semantically usable for general programs.
Review scope
Excluding #2197, this PR changes 29 files with 546 additions and 62 deletions. The first commit is a behavior-preserving platform-hook refactor; the second contains the wasm facility; later commits add CI, make the growth test target-relative, reject unsafe threaded-WASI selection, and preserve the official nil-argument behavior.